from typing import List, TYPE_CHECKING, Union, Callable, ClassVar,Optional, Any
from pydantic import EmailStr,computed_field
from datetime import datetime,date
from sqlmodel import  SQLModel,text,Column,TEXT,Field,Relationship
from .base import SQLModelBase
from .resBase import BaseResponse
import sqlalchemy as sa
from enum import Enum
# from sqlalchemy.orm import Relationship

if TYPE_CHECKING:
    from .userAuth import UserAuth
    from .article import Article
       
# 枚举定义
class UserStatus(str, Enum):
    DISABLED = "DISABLED"
    ENABLED = "ENABLED"
    DELETED = "DELETED"
    
    @classmethod
    def get_chinese_label(cls, status):
        labels = {
            cls.DISABLED: "停用",
            cls.ENABLED: "启用",
            cls.DELETED: "注销"
        }
        return labels.get(status, "未知状态")

class UserType(str, Enum):
    NORMAL = "普通用户"
    VIP = "VIP用户"
    ADMIN = "管理员"

class VerificationPurpose(str, Enum):
    REGISTER = "注册"
    RESET_PASSWORD = "重置密码"
    BIND_NEW = "绑定新账号"

class AccountType(str, Enum):
    PHONE = "手机号"
    EMAIL = "邮箱"
    WECHAT = "微信"
    QQ = "qq"
    WEIBO = "微博"
    
# 工具函数，用于创建标准化的Field
def create_field(
    *,
    title: str,
    comment: str,
    max_length: int | None = None,
    default: Any = None,
    name: str | None = None,
    sa_column: Column | None = None,
    **kwargs
) -> Field:
    if sa_column:
        field_kwargs = {
            "title": title,
            "sa_column": sa_column
        }
    else:
        field_kwargs = {
            "title": title,
            "sa_column_kwargs": {"comment": comment}
        }
        if name:
            field_kwargs["sa_column_kwargs"]["name"] = name
    
    if max_length:
        field_kwargs["max_length"] = max_length
    if default is not None:
        field_kwargs["default"] = default
        
    field_kwargs.update(kwargs)
    return Field(**field_kwargs)

# 基础验证模型
class VerificationBase(SQLModel):
    id: int | None = create_field(title="主键", comment="主键", default=None, primary_key=True)
    expiresAt: datetime = create_field(title="过期时间", comment="过期时间", name="expires_at")
    verifiedTime: datetime | None = create_field(
        title="验证时间",
        comment="验证时间",
        default=None,
        name="verified_time"
    )
    purpose: VerificationPurpose = create_field(title="验证码用途", comment="验证码用途")


# 个人基础资料字段
class ProfileBase(SQLModel):
    headPortrait: str | None = create_field(title="头像", comment="头像", max_length=255, name="head_portrait")
    nickName: str | None = create_field(title="昵称", comment="昵称", max_length=20, name="nick_name")
    birthday: date | None = create_field(title="出生日期", comment="出生日期")
    height: int | None= create_field(title="身高", comment="身高", default=0, 
                             sa_column_kwargs={"server_default": text("0")})
    profession: str | None = create_field(title="职业", comment="职业", max_length=20)
    gender: str | None = create_field(title="性别", comment="性别", max_length=10)
    school: str | None = create_field(title="毕业学校", comment="毕业学校", max_length=100)
    education: str | None = create_field(title="最高学历", comment="最高学历", max_length=20)
    aboutMe: str | None = create_field(title="关于我", comment="关于我", max_length=255, name="about_me")
    interest: str | None = create_field(title="兴趣爱好", comment="兴趣爱好", max_length=255)    
    loveRequirement: str | None = create_field(title="心仪的他", comment="择偶要求", max_length=255, name="love_requirement")
    
    # 位置相关
    lon: str | None = create_field(title="经度", comment="经度", default=None, max_length=50)
    lat: str | None = create_field(title="纬度", comment="纬度", default=None, max_length=50)
    provinceCode: str | None = create_field(title="居住省", comment="居住省", default=None, max_length=20,name="province_code")
    cityCode: str | None = create_field(title="居住市", comment="居住市", default=None, max_length=20,name="city_code")
    homeProvinceCode: str | None = create_field(title="家乡省", comment="家乡省", default=None, max_length=20,name="home_province_code")
    homeCityCode: str | None = create_field(title="家乡市", comment="家乡市", default=None, max_length=20,name="home_city_code")


    # 情感相关
    marriage: str | None = create_field(title="婚姻状况", comment="婚姻状况", default=None, max_length=20)
    loveGoal: str | None = create_field(title="脱单目标", comment="脱单目标", default=None, max_length=100, name="love_goal")
    emotional: str | None = create_field(title="感情状况", comment="感情状况", default=None, max_length=100)
    
    # 其他信息
    annualSalary: str | None = create_field(title="年薪", comment="年薪", default=None, max_length=20, name="annual_salary")
    weChatNumber: str | None = create_field(title="微信号", comment="微信号", default=None, max_length=50, name="we_chat_number")
    imgList: str | None = Field(
        default=None, 
        title="相册",
        sa_column=Column(TEXT, name='img_list', comment="相册")
    )
    educationalType: str | None = create_field(title="学历类型", comment="学历类型", max_length=20, name="educational_type")
    characterType: str | None = create_field(title="性格测试", comment="性格测试", default=None, max_length=500, name="character_type")    
    additional: str | None = create_field(title="附加信息", comment="附加信息", max_length=255)

# 用户基础模型
class UserBase(ProfileBase):              
    account: str = create_field(
        title="主账号",
        comment="用户主账号(手机号/邮箱/第三方账号ID)",
        max_length=255,
        index=True,
        unique=True
    )
    accountType: AccountType = create_field(
        title="账号类型",
        comment="账号类型(phone/email/wechat/qq/weibo)",
        name="account_type",
        default=AccountType.PHONE,
        sa_column_kwargs={"server_default": text("'PHONE'")}
    )
    status: UserStatus = create_field(
        title="用户状态",
        comment="用户状态：DISABLED-停用/ENABLED-启用/DELETED-注销",
        default=UserStatus.DISABLED,
        sa_column_kwargs={"server_default": text("'DISABLED'")}
    )
    userType: UserType = create_field(
        title="用户类型",
        comment="用户类型",
        default=UserType.NORMAL,
        name="user_type",
        sa_column_kwargs={"server_default": text("'NORMAL'")}
    )
    authStatus: str | None = create_field(title="用户认证状态", comment="用户认证状态", default=None, max_length=10, name="auth_status")
    goldBalance: int = create_field(title="金币余额", comment="金币余额", default=0, sa_column_kwargs={"server_default": text("0")})

# 用户数据库模型
class User(UserBase, SQLModelBase, table=True):   
    is_superuser: bool = create_field(
        title="是否超管",
        comment="是否超管默认0",
        default=False,
        name="is_superuser",
        sa_column_kwargs={"server_default": text("'false'")}
    )
    hashed_password: str | None = create_field(title="密码哈希", comment="密码哈希", max_length=255)

    # 定义表参数
    __tablename__: str = "users" 
    __table_args__ = {'comment': '用户表'}
    
    # 关系定义
    userauths: List["UserAuth"] = Relationship(back_populates="user")
    articles: List["Article"] = Relationship(back_populates="user")
    third_party_accounts: List["ThirdPartyAccount"] = Relationship(back_populates="user")
    login_logs: List["LoginLog"] = Relationship(back_populates="user")

# API请求模型
class UserProfileUpdateMe(ProfileBase):
    """用于用户自己更新个人资料的模型"""
    headPortrait: str | None = None
    nickName: str | None = None
    birthday: date | None = None
    height: int | None = None
    profession: str | None = None
    gender: str | None = None
    school: str | None = None
    education: str | None = None
    aboutMe: str | None = None
    interest: str | None = None
    loveRequirement: str | None = None
    lon: str | None = None
    lat: str | None = None
    provinceCode: str | None =None
    cityCode: str | None =None
    homeProvinceCode: str | None =None
    homeCityCode: str | None =None
    marriage: str | None = None
    loveGoal: str | None = None
    emotional: str | None = None
    annualSalary: str | None = None
    weChatNumber: str | None = None
    imgList: str | None = None
    educationalType: str | None = None
    characterType: str | None = None
    additional: str | None = None

    class Config:
        json_encoders = {
            date: lambda v: v.strftime("%Y-%m-%d") if v else None
        }

class UserCreate(SQLModel):
    """创建用户的请求模型"""
    phone: str | None = create_field(title="手机号", comment="手机号", max_length=25)
    email: EmailStr | None = None
    password: str = create_field(title="密码", comment="密码", min_length=8, max_length=40)
    nickName: str | None = create_field(title="昵称", comment="昵称", max_length=20)

class PhoneVerification(VerificationBase, table=True):
    phone: str = create_field(title="手机号", comment="手机号", max_length=25, index=True)
    code: str = create_field(title="验证码", comment="验证码", max_length=16)

    class Config:
        table_name = "phone_verifications" 
        table_description = "手机验证码"

class ThirdPartyAccount(SQLModel, table=True):
    id: int | None = Field(default=None, primary_key=True, title="主键", sa_column_kwargs={"comment": "主键"})        
    thirdPartyId: str|None = Field(default=None, index=True,max_length=255, title="第三方id", sa_column_kwargs={"comment": "第三方id","name":"third_party_id"})    
    thirdPartyType: str|None = Field(max_length=50, title="第三方类型", sa_column_kwargs={"comment": "第三方类型","name":"third_party_type"})        
    user_id: int | None = Field(default=None, foreign_key="users.id")
    user: Optional["User"] = Relationship(back_populates="third_party_accounts")
    # 定义表参数
    __tablename__: str = "third_party_accounts" 
    __table_args__ = {'comment': '第三方账户'}
    

class EmailVerification(VerificationBase, table=True):
    email: EmailStr = create_field(title="邮箱", comment="邮箱地址", max_length=255, index=True)
    token: str = create_field(title="验证token", comment="验证token", max_length=255)

    class Config:
        table_name = "email_verifications" 
        table_description = "邮箱验证码"

# 手机号验证码请求
class PhoneVerificationCodeRequest(SQLModel):
    phone: str = Field(..., description="手机号码")
    purpose: VerificationPurpose = Field(..., description="验证码用途：注册/重置密码/绑定新账号")

# 手机号验证码响应
class PhoneVerificationCodeResponse(BaseResponse):
    data:  None  # 具体的数据字段none

# 手机注册请求
class PhoneRegisterRequest(SQLModel):
    phone: str = Field(..., description="手机号码")
    password: str = Field(..., min_length=8, max_length=255, description="密码")    
    verification_code: str = Field(..., min_length=6, max_length=6, description="短信验证码")
# 手机注册响应
class PhoneRegisterResponse(BaseResponse):
    data:PhoneVerificationCodeRequest|None 



class LoginLog(SQLModel, table=True):    
    id: int | None = Field(default=None, primary_key=True, title="主键", sa_column_kwargs={"comment": "主键"})
    userId: int = Field(foreign_key="users.id",sa_column_kwargs={"comment": "用户唯一id","name":"user_id"})    
    loginTime: datetime | None = Field(
        default=None,
        sa_type=sa.DateTime(timezone=True),
        sa_column_kwargs={"server_default": sa.func.now(),"comment":"登陆时间","name":"login_time"},
        nullable=False,
    )
    ipAddress: str | None = Field(default=None, max_length=50, title="登陆ip", sa_column_kwargs={"comment": "登陆ip","name":"ip_address"})    
    deviceInfo: str | None = Field(default=None, max_length=50, title="登陆设备信息", sa_column_kwargs={"comment": "登陆设备信息","name":"device_info"})    
    
    # 定义表参数
    __tablename__: str = "login_logs" 
    __table_args__ = {'comment': '用户日志表'}
    
    user: User = Relationship(back_populates="login_logs")



class UpdatePassword(SQLModel):
    current_password: str = Field(min_length=8, max_length=40)
    new_password: str = Field(min_length=8, max_length=40)

# 登陆form

from enum import Enum

class LoginType(Enum):
    PHONE = "phone"
    EMAIL = "email"
    WECHAT = "wechat"

class LoginForm(SQLModel):
    code: str  # 使用枚举类型
    username: str  # 用户名（可以是手机号、邮箱或微信号）
    password: str  # 密码


# Properties to return via API, id is always required
class UserPublic(UserProfileUpdateMe):
    @computed_field
    @property
    def age(self) -> int | None:
        if not self.birthday:
            return None
        today = date.today()
        return today.year - self.birthday.year - ((today.month, today.day) < (self.birthday.month, self.birthday.day))



# 登录成功返回内容
class LoginResult(UserPublic):
    id: int | None = None
    account: str | None = None
    accountType: AccountType | None = None    
    token: str | None = None
class TokenResult(SQLModel):
    
    token: str | None = None

class LoginResultResponse(BaseResponse):
    data: TokenResult | None  


class UserMeResult(SQLModel):
    
    username: str | None = None
    roles:list[str]|None = None


class UserMeResponse(BaseResponse):
    data: UserMeResult | None     
 
class UserPublicResponse(BaseResponse):
    data: UserPublic | None  # 具体的数据字段类型为 UserPublic


class UsersPublicResponse(BaseResponse):
    data: list[UserPublic] | None  # 具体的数据字段类型为 [UserPublic]

class CaptchaResponse(BaseResponse):
    data: str  # 验证码图片URL
